from django.shortcuts import render,HttpResponse
from django.contrib.auth.hashers import check_password
from django.contrib.auth import authenticate
from rest_framework.views import APIView
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import AbstractUser
from django.contrib.auth.hashers import check_password
from collects.utils import check_login
import re
from .models import User,UserAddr
from rest_framework.response import Response


# Create your views here.

class Users(APIView):
    def get(self,request,name):
        if not re.findall('^[A-Za-z]\w{4,19}$',name):
            return Response({
                'code':400,
                'msg':'匹配不成功'
            })

        sre = User.objects.filter(username=name)
        if sre:
            return Response({
                'code':404,
                'msg':'账号重复'
            })

        return Response({
            'code':200,
            'msg':'pok'
        })


class Userc(APIView):
    def get(self,request,mod):
        if not re.findall('^1[3-8]\d{9}$',mod):
            return Response({
                'code':400,
                'msg':'格式不正确'
            })

        dada = User.objects.filter(mobile=mod)
        if dada:
            return Response({
                'code':404,
                'msg':'手机号重复'
            })

        return Response({
            'code': 200,
            'msg': '成功'
        })

import random
import redis
# 标准内置模板  生成数字和字母
import string
from captcha.image import ImageCaptcha
# 图片验证码的视图
class ImgeCode(APIView):
    def get(self,request,uuid):
        # 生成一个随机码
        code = ''.join(random.sample(string.ascii_letters + string.digits,4))
        # 实例化一个图片验证码的对象
        img = ImageCaptcha()
        imge_code = img.generate(code)  # 字节io对象

        # 验证码存入redis
        redis_conn = redis.Redis(host='localhost',port=6379,password='123321')
        # 存储图片验证码
        redis_conn.set(uuid,code,ex=60 * 5)
        # 返回响应
        return HttpResponse(imge_code,content_type='image/png')

    def post(self,request,uuid):
        # 获取前端输入的验证码
        image_code = request.data.get('imageCode')
        print('xxxxxxxx',uuid)
        print('xxxxx',image_code)


        # decode()   lower
        # 与redis对比验证码 取出的数据是字节串
        redis_conn = redis.Redis(host='localhost',port=6379,password='123321')
        stored_code = redis_conn.get(uuid)
        if not stored_code:
            return Response({
                'code':400,
                'msg':'验证码已过期'
            })

        # 验证码存在解码对比
        if stored_code.decode().lower() == image_code.lower():
            return Response({
                'code':200,
                'msg':'验证成功',
            })



        return Response({
            'code':400,
            'msg':'验证码错误'
        })

# 注册
class RegisterAPIView(APIView):
    def post(self,request):
        # 获取前端数据
        username = request.data.get('name')
        password = request.data.get('pass')
        confirm_pass = request.data.get('confirmPass')
        mobile = request.data.get('mobile')
        print('xxxxxxa',username)
        print('xxxxxxa', password)
        print('xxxxxxa', mobile)

        # 数据验证
        if not all([username,password,mobile]):
            return Response({
                'code': 400,
                'msg': '注册信息不完整'
            })

        # 验证账号是否重复
        if User.objects.filter(username=username):
            return Response({
                'code': 401,
                'msg': '用户名重复'
            })
        # 验证手机号是否重复
        if User.objects.filter(mobile=mobile):
            return Response({
                'code': 402,
                'msg': '手机号重复'
            })
        # 存入数据库  create_user哈希加密
        User.objects.create_user(username=username,password=password,mobile=mobile)

        return Response({
            'code':200,
            'msg':'注册成功'
        })

import time
import jwt
from django.conf import settings
from django.db import models
# 登入
class Login(APIView):
    def post(self,request):
        # 接受前端数据
        name = request.data.get('name')
        password = request.data.get('pass')

        print('是否返回：',name)
        print('是否返回：', password)


        # 验证当前用户是否存在
        users = User.objects.filter(models.Q(username=name)|models.Q(mobile=name)).first()
        # users = authenticate(username=name)
        print('查询集都有哪些方法',dir(users))
        if not users:
            return Response({
                'code':400,
                'msg':'用户名错误'
            })
        # 用户密码是否正确
        if check_password(password, users.password):
            # 使用jwt做会话保持
            # 返回字符串
            token = self.gen_token(users)

            return Response({
                'code': 200,
                'msg': '登入成功',
                'username': users.username,
                'token':token,
            })

        return Response({
            'code': 400,
            'msg': '密码错误'
        })

    # 静态方法
    @ staticmethod
    def gen_token(user):
        """
         :param user: 用户对象
         :return: 生成的token
        """
        payload = {
            'user_id' : user.id,
            'username': user.username,
            'exp': time.time() + 99999
        }

        # 编码生成token
        # 哈希加密
        token = jwt.encode(payload, settings.SECRET_KEY, algorithm='HS256')
        return token



# 用户信息的视图

class UserInfoAPIView(APIView):
    # 加载用户的信息
    @check_login
    def get(self,request):
        # 获取用户当前信息
        user = request.user

        # 查询当前用户的所有收获地址 反向查询
        addrs = user.useraddr_set.all()
        temp = []
        if addrs:
            for i in addrs:
                temp_dict = {
                    'id':i.id,
                    'receiver':i.receiver,
                    'receiver_mobile':i.receive_mobile,
                    'receiver_addr':i.receive_addr,
                    "is_default":i.is_default
                }
                temp.append(temp_dict)

        # 组织用户的数据  待实现
        data = {
            'code':200,
            'msg':'获取用户信息成功!',
            'userInfo':{
                'username':user.username,
                'phone':user.mobile,
                'addrs':temp
        }
        }

        return Response({
            'code': 200,
            'msg': '加载用户信息成功',
            'addrs': data
        }
        )

    # 更新用户信息
    @check_login
    def put(self,request):
        # 接受前端请求
        module = request.data.get('module')
        addrs = request.data.get('addrs')
        print('接受的前端数据',module,addrs)
        # 接受用户信息
        user = request.user
        print('当前用户对象',user)


        # 更新数据库数据
        update_mobile = False
        update_addr = False

        # 处理手机号的更新
        user_queryset = User.objects.filter(id=user.id,mobile=module)
        if not user_queryset:
            # 说明用户手机号更新
            update_mobile = True
            user.mobile = module
            user.save()

        # 处理用户地址的更新
        for i in addrs:
            # i 就是地址字典
            addr_queryset = UserAddr.objects.filter(id=i.get('id'),receiver=i.get('receiver'),receive_mobile=i.get('receiver_mobile'),receive_addr=i.get('receiver_addr'),is_default=i.get('is_default'))
            if not addr_queryset:
                # 说明当前地址更新了
                update_addr = True
                # 开始更新数据
                if i.get('is_default'):
                    UserAddr.objects.filter(user_id=user).update(is_default=False)

                # 更新当前的地址
                UserAddr.objects.filter(id=i.get('id')).update(receiver=i.get('receiver'),receive_mobile=i.get('receiver_mobile'),receive_addr=i.get('receiver_addr'),is_default=i.get('is_default'))

        # 返回响应
        return Response({
            'code':200,
            'msg':'更新信息成功' if update_mobile or update_addr else '尚未更新信息'
        })



class Userddr(APIView):
    @check_login
    def post(self,request):
        # 接受前端数据
        receiver = request.data.get('receiver')
        receive_mobile = request.data.get('receive_mobile')
        receive_addr = request.data.get('receive_addr')
        is_default = request.data.get('is_default')
        print('xiaodada',receiver,receive_mobile,receive_addr,is_default)

        # 获取用户的信息
        user = request.user
        print('用户',user)


        # 对用户添加的数据，进行完整性校验
        if not receiver or not receive_mobile or not receive_addr:
            return Response({
                'code':400,
                'msg':'地址信息不完整',
            })




        # 将用户的地址数据存入数据库
        if is_default:
            # 将用户的其他地址改为非默认
            UserAddr.objects.filter(user_id=user).update(is_default=False)

        addr = UserAddr.objects.create(receiver=receiver,receive_mobile=receive_mobile,receive_addr=receive_addr,is_default=is_default,user_id=user)


        # 返回响应
        return Response({
            'code':200,
            'msg':'添加数据成功',
            'addr':{
                'id':addr.id,
                'receiver':addr.receiver,
                'receiver_mobile':addr.receive_mobile,
                'receiver_addr':addr.receive_addr,
                'is_default':addr.is_default,
            }
        })


    def delete(self,request):
        # 接受前端信息
        addr_id = request.data.get('addr_id')

        # 根据地址id查询地址对象，并删除
        UserAddr.objects.filter(id=addr_id).delete()

        # 返回响应
        return Response({
            'code':200,
            'msg':'删除成功'
        })


# 修改用户的密码
class UpdatePw(APIView):
    @check_login
    def put(self,request):
        # 接受前端的数据
        originPw = request.data.get('originPw')
        freshPw = request.data.get('freshPw')
        cofirmPw = request.data.get('cofirmPw')

        # 用户的信息
        user = request.user

        # 验证当前用户原始密码对不对，若验证通过，则更新用户的密码
        check = check_password(originPw,user.password)
        # 返回响应
        if not check:
            return Response({
                'code':400,
                'msg':'输入的原始密码不正确'
            })
        if freshPw != cofirmPw:
            return Response({
                'code':401,
                'msg':'更新的两次密码不一致'
            })
        if originPw == freshPw:
            return Response({
                'code':402,
                'msg':'密码尚未更新'
            })
        user.set_password(freshPw)
        user.save()

        return Response({
            'code':200,
            'msg':'修改密码成功！'
        })
